﻿
//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#include "QFamilyTreeWidgetUtil.h"
#include "IFamily.h"
#include "IDocument.h"
#include "ICategory.h"
#include "IGroupType.h"
#include "IUiDocument.h"
#include "IFamilyType.h"
#include "JournalUtils.h"
#include "ICommandManager.h"
#include "ICategoryLibrary.h"
#include "CommandParameters.h"
#include "IImportCADElement.h"
#include "IJournalCommandData.h"
#include "IFamilyConfigElement.h"
#include "IUiDocumentViewManager.h"
#include "IElementBasicInformation.h"
#include "GcmpBuiltInCategoryUniIdentities.h"

#include <QMouseEvent>
#include "UIComponent.h"
#include "DocumentUtils.h"
// #include "ImportCADElement.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;
using namespace Sample;

const QString QFamilyTreeWidgetUtil::s_familyText = QString::fromStdWString(GBMP_TR(L"族"));
const QString QFamilyTreeWidgetUtil::s_importedObjectText = QString::fromStdWString(GBMP_TR(L"导入对象"));
const QString QFamilyTreeWidgetUtil::s_cadSheetCategoryText = QString::fromStdWString(GBMP_TR(L"图纸"));
const QString QFamilyTreeWidgetUtil::s_skpCategoryText = QString::fromStdWString(GBMP_TR(L"SKP模型"));
const QString QFamilyTreeWidgetUtil::s_groupTypeText = QString::fromStdWString(GBMP_TR(L"组类型"));

namespace
{
    bool IsCADSheet(const std::wstring& familyName)
    {
        // ends with ".dxf" or ".dwg"?
        if (familyName.length() > 4)
        {
            std::wstring extention = familyName.substr(familyName.length() - 4);
            if (gcmp::StrICmp(extention.c_str(), L".dxf") == 0 || gcmp::StrICmp(extention.c_str(), L".dwg") == 0
                || gcmp::StrICmp(extention.c_str(), L".pdf") == 0)
                return true;
        }

        return false;
    }

    bool IsSKPModel(const std::wstring& familyName)
    {
        // ends with ".skp"?
        if (familyName.length() > 4)
        {
            std::wstring extention = familyName.substr(familyName.length() - 4);
            if (gcmp::StrICmp(extention.c_str(), L".skp") == 0)
                return true;
        }

        return false;
    }

    bool IsGroupType(const IElement* pElement)
    {
        const IGroupType* pGroupType = quick_cast<const IGroupType>(pElement);
        return pGroupType != nullptr;
    }

    void BuildImportedObjectWidgetItems(QTreeWidgetItem* pImportedObject,
        const std::wstring& categoryText,
        std::map<std::wstring, IElement*>& itemsToBeAdded,
        QIconMap& mapIcons,
        const QString& iconCategoryPath,
        const QString& iconPath,
        int categoryNodeType,
        int nodeType)
    {
        QTreeWidgetItem* pImporteObjectCategory = QFamilyTreeWidgetUtil::FindChildWidgetItem(pImportedObject, categoryText);
        if (itemsToBeAdded.empty())
        {
            if (pImporteObjectCategory)
            {
                OwnerPtr<QTreeWidgetItem> opImportedObjectCategory(pImporteObjectCategory);
                pImportedObject->removeChild(pImporteObjectCategory);
            }
        }
        else
        {
            if (!pImporteObjectCategory)
            {
                OwnerPtr<QTreeWidgetItem> opImportedObjectCategory = NEW_AS_OWNER_PTR(QTreeWidgetItem, pImportedObject);
                opImportedObjectCategory->setIcon(0, mapIcons.GetIcon(iconCategoryPath));
                opImportedObjectCategory->setText(0, QString::fromStdWString(categoryText));
                opImportedObjectCategory->setData(0, IMPORT_USER_DATA_ROLE, QVariant(categoryNodeType));
                pImporteObjectCategory = opImportedObjectCategory.get();
                pImportedObject->addChild(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opImportedObjectCategory));
            }
            DBG_WARN_AND_RETURN_VOID_UNLESS(pImporteObjectCategory, L"pImporteObjectCategory为空",L"GDMP",L"2023-10-20");

            std::vector<QTreeWidgetItem*> itemsToBeDeleted;
            int itemCount = pImporteObjectCategory->childCount();
            for (int i = 0; i < itemCount; ++i)
            {
                QTreeWidgetItem* pItem = pImporteObjectCategory->child(i);
                std::wstring itemName = pItem->text(0).toStdWString();

                auto itr = itemsToBeAdded.find(itemName);
                if (itr == itemsToBeAdded.end())
                {
                    itemsToBeDeleted.push_back(pItem);
                }
                else
                {
                    // 已经在树里，不用再增加节点了
                    itemsToBeAdded.erase(itr);
                }
            }

            FOR_EACH(pItem, itemsToBeDeleted)
            {
                OwnerPtr<QTreeWidgetItem> opItem(pItem);
                DBG_WARN_AND_RETURN_VOID_UNLESS(opItem, L"opItem为空",L"GDMP",L"2023-10-20");
                pImporteObjectCategory->removeChild(pItem);
            }

            // 把不在树里的节点加上去
            for (auto itr = itemsToBeAdded.begin(); itr != itemsToBeAdded.end(); ++itr)
            {
                OwnerPtr<QTreeWidgetItem> opItem = NEW_AS_OWNER_PTR(QTreeWidgetItem, pImporteObjectCategory);
                DBG_WARN_AND_RETURN_VOID_UNLESS(opItem, L"opItem为空",L"GDMP",L"2023-10-20");
                opItem->setIcon(0, mapIcons.GetIcon(iconPath));
                opItem->setText(0, QString::fromStdWString(itr->second->GetBasicInformation()->GetName()));
                opItem->setData(0, IMPORT_USER_DATA_ROLE, QVariant(nodeType));
                {
                    IElement* pElement = itr->second;
                    // 把FamilyType信息加进去，在插入族实例时需要该信息。
                    IFamily* pFamily = quick_cast<IFamily>(pElement);
                    if (pFamily)
                    {
                        const std::vector<const IFamilyType*> familyTypes = pFamily->GetFamilyTypes();
                        DBG_WARN_AND_CONTINUE_UNLESS(familyTypes.size() == 1, L"导入对象的FamilyType只有一个",L"GDMP",L"2023-10-20");
                        std::wstring familyTypeName = familyTypes[0]->GetName();
                        opItem->setData(0, IMPORT_ITEM_FAMILY_TYPE, QVariant(QString::fromStdWString(familyTypeName)));
                    }
                }

                pImporteObjectCategory->addChild(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opItem));
            }

            pImporteObjectCategory->setExpanded(true);
            pImporteObjectCategory->sortChildren(0, Qt::AscendingOrder);
        }
    }

void BuildGroupObjectWidgetItems(QTreeWidgetItem* pImportedObject,
    const std::wstring& categoryText,
    std::map<std::wstring, IElement*>& itemsToBeAdded,
    QIconMap& mapIcons,
    const QString& iconCategoryPath,
    const QString& iconPath,
    int categoryNodeType,
    int nodeType)
{
    QTreeWidgetItem* pImporteObjectCategory = QFamilyTreeWidgetUtil::FindChildWidgetItem(pImportedObject, categoryText);
    if (itemsToBeAdded.empty())
    {
        if (pImporteObjectCategory)
        {
            OwnerPtr<QTreeWidgetItem> opImportedObjectCategory(pImporteObjectCategory);
            pImportedObject->removeChild(pImporteObjectCategory);
        }
    }
    else
    {
        if (!pImporteObjectCategory)
        {
            OwnerPtr<QTreeWidgetItem> opImportedObjectCategory = NEW_AS_OWNER_PTR(QTreeWidgetItem, pImportedObject);
            opImportedObjectCategory->setIcon(0, mapIcons.GetIcon(iconCategoryPath));
            opImportedObjectCategory->setText(0, QString::fromStdWString(categoryText));
            opImportedObjectCategory->setData(0, IMPORT_USER_DATA_ROLE, QVariant(categoryNodeType));
            pImporteObjectCategory = opImportedObjectCategory.get();
            pImportedObject->addChild(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opImportedObjectCategory));
        }
        DBG_WARN_AND_RETURN_VOID_UNLESS(pImporteObjectCategory, L"pImporteObjectCategory为空",L"GDMP",L"2023-10-20");

        std::vector<QTreeWidgetItem*> itemsToBeDeleted;
        int itemCount = pImporteObjectCategory->childCount();
        for (int i = 0; i < itemCount; ++i)
        {
            QTreeWidgetItem* pItem = pImporteObjectCategory->child(i);
            std::wstring itemName = pItem->text(0).toStdWString();

            auto itr = itemsToBeAdded.find(itemName);
            if (itr == itemsToBeAdded.end())
            {
                itemsToBeDeleted.push_back(pItem);
            }
            else
            {
                // 已经在树里，不用再增加节点了
                itemsToBeAdded.erase(itr);
            }
        }

        FOR_EACH(pItem, itemsToBeDeleted)
        {
            OwnerPtr<QTreeWidgetItem> opItem(pItem);
            pImporteObjectCategory->removeChild(pItem);
        }

        // 把不在树里的节点加上去
        for (auto itr = itemsToBeAdded.begin(); itr != itemsToBeAdded.end(); ++itr)
        {
            OwnerPtr<QTreeWidgetItem> opItem = NEW_AS_OWNER_PTR(QTreeWidgetItem, pImporteObjectCategory);
            opItem->setIcon(0, mapIcons.GetIcon(iconPath));

            IElementBasicInformation* pElementBasicInfo = itr->second->GetBasicInformation();
            DBG_WARN_AND_CONTINUE_UNLESS(pElementBasicInfo, L"pElementBasicInfo为空",L"GDMP",L"2023-10-20");
            opItem->setText(0, QString::fromStdWString(pElementBasicInfo->GetName()));
            opItem->setData(0, GROUP_USER_DATA_ROLE, QVariant(nodeType));          

            pImporteObjectCategory->addChild(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opItem));
        }

        pImporteObjectCategory->setExpanded(true);
        pImporteObjectCategory->sortChildren(0, Qt::AscendingOrder);
    }
}
}

//////////////////////////////////////////////////////////////////////////
/// QFamilyTreeWidgetUtil implement
QTreeWidgetItem* QFamilyTreeWidgetUtil::AddFamilyCategoryWidgetItem(QTreeWidgetItem* pParent, const QString& categoryName, QIconMap& mapIcons)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pParent, L"pParent为空",L"GDMP",L"2023-10-20");
    QTreeWidgetItem* pCategoryItem = nullptr;
    OwnerPtr<QTreeWidgetItem> categoryItem = NEW_AS_OWNER_PTR(QTreeWidgetItem, pParent);
    categoryItem->setIcon(0, mapIcons.GetIcon(GetIconPathByFamilyCategoryName(categoryName.toStdWString())));
    categoryItem->setText(0, categoryName);
    categoryItem->setData(0, FAMILY_USER_DATA_ROLE, QVariant(TWNT_FAMILY_CATEGORY));
    categoryItem->setExpanded(true);
    pCategoryItem = categoryItem.get();
    pParent->addChild(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(categoryItem));
    return pCategoryItem;
}

QTreeWidgetItem * QFamilyTreeWidgetUtil::FindChildWidgetItem(QTreeWidgetItem * pParent, const std::wstring & itemName)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pParent, L"pParent为空",L"GDMP",L"2023-10-20");
    for (int ii = 0; ii < pParent->childCount(); ++ii)
    {
        QTreeWidgetItem* pItem = pParent->child(ii);
        if (pItem && pItem->text(0).toStdWString() == itemName)
        {
            return pItem;
        }
    }

    return nullptr;
}
void QFamilyTreeWidgetUtil::AddFamilyWidgetItem(QTreeWidgetItem * pParent, gcmp::IFamily * pFamily, QIconMap & mapIcons)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pParent, L"pParent为空",L"GDMP",L"2023-10-20");
    std::wstring strName = pFamily->GetBasicInformation()->GetName();
    OwnerPtr<QTreeWidgetItem> familyItem = NEW_AS_OWNER_PTR(QTreeWidgetItem, pParent);
    familyItem->setIcon(0, mapIcons.GetIcon(GetIconPathByFamilyName(strName)));
    familyItem->setData(0, FAMILY_USER_DATA_ROLE, QVariant(TWNT_FAMILY));

    //添加族类型节点
    const std::vector<const IFamilyType*> familyTypes = pFamily->GetFamilyTypes();
    FOR_EACH(familyType, familyTypes)
    {
        OwnerPtr<QTreeWidgetItem> familyTypeItem = NEW_AS_OWNER_PTR(QTreeWidgetItem, familyItem.get());
        // TODO: 现在这个数据将来可以扩展
        familyTypeItem->setIcon(0, mapIcons.GetIcon(GetIconPathByFamilyTypeName(familyType->GetName())));
        familyTypeItem->setText(0, QString::fromStdWString(familyType->GetName()));
        familyTypeItem->setData(0, FAMILY_USER_DATA_ROLE, QVariant(TWNT_FAMILYTYPE));
        familyItem->addChild(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(familyTypeItem));
    }

    familyItem->setText(0, QString::fromStdWString(strName));
    familyItem->setExpanded(true);
    pParent->addChild(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(familyItem));
}
void QFamilyTreeWidgetUtil::UpdateFamilyWidgetItem(QTreeWidgetItem* pFamilyItem, gcmp::IFamily* pFamily, QIconMap& mapIcons)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pFamilyItem, L"pFamilyItem为空",L"GDMP",L"2023-10-20");
    DBG_WARN_AND_RETURN_VOID_UNLESS(pFamily, L"pFamily为空",L"GDMP",L"2023-10-20");

    std::wstring familyName = pFamily->GetBasicInformation()->GetName();
    int familyInstanceCount = 0;

    //添加族类型节点
    auto familyTypes = pFamily->GetFamilyTypes();
    FOR_EACH(familyType, familyTypes)
    {
        QTreeWidgetItem* pTypeItem = FindChildWidgetItem(pFamilyItem, familyType->GetName());
        if (pTypeItem == nullptr)
        {
            OwnerPtr<QTreeWidgetItem> familyTypeItem = NEW_AS_OWNER_PTR(QTreeWidgetItem, pFamilyItem);
            pTypeItem = familyTypeItem.get();
            pFamilyItem->addChild(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(familyTypeItem));

            pTypeItem->setIcon(0, mapIcons.GetIcon(GetIconPathByFamilyTypeName(familyType->GetName())));
            pTypeItem->setData(0, FAMILY_USER_DATA_ROLE, QVariant(TWNT_FAMILYTYPE));
        }
        else
        {
            pTypeItem->setFlags(pFamilyItem->flags() & ~Qt::ItemIsTristate);
        }

        pTypeItem->setText(0, QString::fromStdWString(familyType->GetName()));
    }

    DeleteDirtyChildItem(pFamilyItem);

    pFamilyItem->setText(0, QString::fromStdWString(familyName));
    pFamilyItem->setFlags(pFamilyItem->flags() & ~Qt::ItemIsTristate);
}
QString QFamilyTreeWidgetUtil::GetIconPathForFamilyRootItem()
{
    const static std::wstring s_rootItemIconPath = L":/images/ResManager/FamilyManagerRootItem.png";
    return QString::fromStdWString(s_rootItemIconPath);
}

QString QFamilyTreeWidgetUtil::GetIconPathByFamilyCategoryName(const std::wstring & categoryName)
{
    const static std::wstring s_categoryIconPath = L":/images/ResManager/FamilyCategory.png";
    return QString::fromStdWString(s_categoryIconPath);
}

QString QFamilyTreeWidgetUtil::GetIconPathByFamilyName(const std::wstring & familyName)
{
    const static std::wstring s_familyIconPath = L":/images/ResManager/Family.png";
    return QString::fromStdWString(s_familyIconPath);
}

QString QFamilyTreeWidgetUtil::GetIconPathByFamilyTypeName(const std::wstring & familyTypeName)
{
    const static std::wstring s_familyTypeIconPath = L":/images/ResManager/FamilyType.png";
    return QString::fromStdWString(s_familyTypeIconPath);
}

QString QFamilyTreeWidgetUtil::GetIconPathForImportedObject()
{
    const static std::wstring s_importedObjectRootItemIconPath = L":/images/ResManager/family_loading.png";
    return QString::fromStdWString(s_importedObjectRootItemIconPath);
}

QString QFamilyTreeWidgetUtil::GetIconPathForCADSheetCategory()
{
    const static std::wstring s_cadSheetCategoryIconPath = L":/images/ResManager/FamilyCategory.png";
    return QString::fromStdWString(s_cadSheetCategoryIconPath);
}

QString QFamilyTreeWidgetUtil::GetIconPathForCADSheet()
{
    const static std::wstring s_cadSheetIconPath = L":/images/ResManager/imported_cad.png";
    return QString::fromStdWString(s_cadSheetIconPath);
}

QString QFamilyTreeWidgetUtil::GetIconPathForSKPCategory()
{
    const static std::wstring s_skpCategoryIconPath = L":/images/ResManager/FamilyCategory.png";
    return QString::fromStdWString(s_skpCategoryIconPath);
}

QString QFamilyTreeWidgetUtil::GetIconPathForSKP()
{
    const static std::wstring s_skpIconPath = L":/images/ResManager/family_loading.png";
    return QString::fromStdWString(s_skpIconPath);
}

void QFamilyTreeWidgetUtil::MarkFamilyAndTypeWidgetItemDirty(QTreeWidgetItem * pRoot)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pRoot, L"pRoot为空",L"GDMP",L"2023-10-20");
    for (int ii = 0; ii < pRoot->childCount(); ++ii)
    {
        QTreeWidgetItem* pCategoryItem = pRoot->child(ii);
        for (int jj = 0; jj < pCategoryItem->childCount(); ++jj)
        {
            QTreeWidgetItem* pFamilyItem = pCategoryItem->child(jj);
            pFamilyItem->setFlags(pFamilyItem->flags() | Qt::ItemIsTristate);
            for (int kk = 0; kk < pFamilyItem->childCount(); ++kk)
            {
                QTreeWidgetItem* pTypeItem = pFamilyItem->child(kk);
                pTypeItem->setFlags(pTypeItem->flags() | Qt::ItemIsTristate);
            }
        }
    }
}
void QFamilyTreeWidgetUtil::DeleteDirtyChildItem(QTreeWidgetItem* pParent)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pParent, L"pParent为空",L"GDMP",L"2023-10-20");
    std::vector<QTreeWidgetItem*> itemToBeDeleted;
    for (int ii = 0; ii < pParent->childCount(); ++ii)
    {
        QTreeWidgetItem* pItem = pParent->child(ii);
        if ((pItem->flags() & Qt::ItemIsTristate) != 0)
        {
            itemToBeDeleted.push_back(pItem);
        }
    }

    FOR_EACH(pItem, itemToBeDeleted)
    {
        OwnerPtr<QTreeWidgetItem> opItem(pItem);
        pParent->removeChild(pItem);
    }
}
void QFamilyTreeWidgetUtil::UpdateFamilyItems(QTreeWidgetItem *pFamilyRootItem, IDocument* pDoc, QIconMap& mapIcons)
{
    //首先需要删除之前添加的节点
    DBG_WARN_AND_RETURN_VOID_UNLESS(pFamilyRootItem, L"pFamilyRootItem指针为空",L"GDMP",L"2023-10-20");
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc != nullptr, L"pDoc指针为空",L"GDMP",L"2023-10-20");

    std::vector<IFamily*> pFamilies = IFamily::GetAllFamilies(pDoc);
    // 去除类族导入对象
    QFamilyTreeWidgetUtil::FilterOutImportedObjects(pFamilies);

    pFamilyRootItem->setIcon(0, mapIcons.GetIcon(GetIconPathForFamilyRootItem()));
    pFamilyRootItem->setData(0, FAMILY_USER_DATA_ROLE, QVariant(TWNT_FAMILY_ROOT));
    int famCount = (int)pFamilies.size();

    MarkFamilyAndTypeWidgetItemDirty(pFamilyRootItem);
    //添加族节点
    FOR_EACH(pFamily, pFamilies)
    {
        const ICategory* pCategory = ICategoryLibrary::Get(pDoc)->GetCategory(pFamily->GetBasicInformation()->GetCategoryUid());
        DBG_WARN_AND_CONTINUE_UNLESS(pCategory, L"pCategory为空",L"GDMP",L"2023-10-20");
        QTreeWidgetItem* pCategoryItem = FindChildWidgetItem(pFamilyRootItem, pCategory->GetName());
        if (pCategoryItem == nullptr)
        {
            pCategoryItem = AddFamilyCategoryWidgetItem(pFamilyRootItem, QString::fromStdWString(pCategory->GetName()), mapIcons);
        }

        if (pCategoryItem->isHidden())
        {
            pCategoryItem->setHidden(false);
        }

        QTreeWidgetItem* pFamilyItem = FindChildWidgetItem(pCategoryItem, pFamily->GetBasicInformation()->GetName());
        if (pFamilyItem)
        {
            UpdateFamilyWidgetItem(pFamilyItem, pFamily, mapIcons);
        }
        else
        {
            AddFamilyWidgetItem(pCategoryItem, pFamily, mapIcons);
        }
    }

    std::vector<QTreeWidgetItem*> categoryToBeDeleted;
    for (int ii = 0; ii < pFamilyRootItem->childCount(); ++ii)
    {
        QTreeWidgetItem* pCategoryItem = pFamilyRootItem->child(ii);
        DeleteDirtyChildItem(pCategoryItem);

        if (pCategoryItem->childCount() == 0)
        {
            categoryToBeDeleted.push_back(pCategoryItem);
        }
    }

    FOR_EACH(pCategoryItem, categoryToBeDeleted)
    {
        OwnerPtr<QTreeWidgetItem> opCategoryItem(pCategoryItem);
        pFamilyRootItem->removeChild(pCategoryItem);
    }

    pFamilyRootItem->sortChildren(0, Qt::AscendingOrder);
}

void QFamilyTreeWidgetUtil::UpdateImportedObjectItems(QTreeWidget* pTreeWidget, gcmp::IDocument* pDoc, QIconMap& mapIcons)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pTreeWidget, L"pTreeWidget为空",L"GDMP",L"2023-10-20");
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc为空",L"GDMP",L"2023-10-20");

    std::vector<IFamily*> pFamilies = IFamily::GetAllFamilies(pDoc);
    // 类族导入对象
    std::vector<IElement*> importedObjects = FilterOutImportedObjects(pFamilies);

    // 类CAD导入对象
    std::vector<IElement*> importCADElements = pDoc->GetElementsByCategory(BuiltInCategoryUniIdentities::BICU_IMPORTED_CAD_OBJECT);
    std::move(importCADElements.begin(), importCADElements.end(), std::back_inserter(importedObjects));

    /*/ TODO：
    // 组类型对象
    std::vector<IElement*> groupTypes = GbmpDocUtils::GetElementsByCategory(pDoc, BuiltInCategoryUniIdentities::BICU_GROUP_TYPE);
    std::move(groupTypes.begin(), groupTypes.end(), std::back_inserter(importedObjects));
    */

    //// 构造导入对象节点
    BuildImportedObjectWidgetItems(pTreeWidget, mapIcons, importedObjects);

}

void QFamilyTreeWidgetUtil::UpdateGroupObjectItems(QTreeWidget* pTreeWidget, gcmp::IDocument* pDoc, QIconMap& mapIcons)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pTreeWidget, L"pTreeWidget为空",L"GDMP",L"2023-10-20");
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc为空",L"GDMP",L"2023-10-20");

    // 组类型对象
    /*/ TODO：组暂时不支持
    // std::vector<IElement*> groupTypes = Sample::DocumentUtils::GetElementsByCategory(pDoc, BuiltInCategoryUniIdentities::BICU_GROUP_TYPE);

    //// 构造组节点
    BuildGroupObjectWidgetItems(pTreeWidget, mapIcons, groupTypes);
    */
}

QTreeWidgetItem* QFamilyTreeWidgetUtil::FindTopLevelWidgetItem(QTreeWidget* pTreeWidget, const QString& itemName)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pTreeWidget, L"pTreeWidget为空",L"GDMP",L"2023-10-20");

    if (pTreeWidget == nullptr)
    {
        return nullptr;
    }
    for (int i = 0; i < pTreeWidget->topLevelItemCount(); ++i)
    {
        QTreeWidgetItem* pTopLevelItem = pTreeWidget->topLevelItem(i);
        if (pTopLevelItem && pTopLevelItem->text(0) == itemName)
        {
            return pTopLevelItem;
        }
    }

    return nullptr;
}
//////////////////////////////////////////////////////////////////////////
// 导入对象
void QFamilyTreeWidgetUtil::BuildImportedObjectWidgetItems(QTreeWidget* pTreeWidget, QIconMap& mapIcons, const std::vector<IElement*>& importedObjects)
{
    if (pTreeWidget == nullptr)
        return;
    // 导入对象 节点
    QTreeWidgetItem* pImportedObject = FindTopLevelWidgetItem(pTreeWidget, s_importedObjectText);
    if (importedObjects.empty())
    {
        if (pImportedObject)
        {
            int importedObjectIndex = pTreeWidget->indexOfTopLevelItem(pImportedObject);
            OwnerPtr<QTreeWidgetItem> opImportedObject(pTreeWidget->takeTopLevelItem(importedObjectIndex));
        }
        return;
    }

    if (!pImportedObject)
    {
        OwnerPtr<QTreeWidgetItem> opImportedObject = NEW_AS_OWNER_PTR(QTreeWidgetItem, pTreeWidget);
        opImportedObject->setIcon(0, mapIcons.GetIcon(GetIconPathForImportedObject()));
        opImportedObject->setText(0, s_importedObjectText);
        opImportedObject->setData(0, IMPORT_USER_DATA_ROLE, QVariant(TWNT_IMPORTED_OBJECT_ROOT));
        pImportedObject = opImportedObject.get();
        int itemCount = pTreeWidget->topLevelItemCount();
        pTreeWidget->insertTopLevelItem(itemCount,TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opImportedObject));
    }
    DBG_WARN_AND_RETURN_VOID_UNLESS(pImportedObject, L"pImportedObject为空",L"GDMP",L"2023-10-20");

    // CAD图纸 节点
    std::map<std::wstring, IElement*> cadSheetsToBeAdded;
    // SKP模型
    std::map<std::wstring, IElement*> skpToBeAdded;
//     GroupType
//         std::map<std::wstring, IElement*> groupTypeAdded;
    FOR_EACH(pElement, importedObjects)
    {
        if (IsCADSheet(pElement->GetBasicInformation()->GetName()))
            cadSheetsToBeAdded.insert(std::make_pair(pElement->GetBasicInformation()->GetName(), pElement));
        else if (IsSKPModel(pElement->GetBasicInformation()->GetName()))
            skpToBeAdded.insert(std::make_pair(pElement->GetBasicInformation()->GetName(), pElement));
//         else if (IsGroupType(pElement))
//         {
//             const IGroupType* pGroupType = quick_cast<const IGroupType>(pElement);
//             if (pGroupType)
//             {
//                 groupTypeAdded.insert(std::make_pair(pGroupType->GetName(), pElement));
//             }            
//         }
    }

    ::BuildImportedObjectWidgetItems(pImportedObject, s_cadSheetCategoryText.toStdWString(), cadSheetsToBeAdded, mapIcons, GetIconPathForCADSheetCategory(), GetIconPathForCADSheet(), TWNT_CAD_SHEET_CATEGORY, TWNT_CAD_SHEET);
    ::BuildImportedObjectWidgetItems(pImportedObject, s_skpCategoryText.toStdWString(), skpToBeAdded, mapIcons, GetIconPathForSKPCategory(), GetIconPathForSKP(), TWNT_SKP_MODEL_CATEGORY, TWNT_SKP_MODEL);
    //::BuildImportedObjectWidgetItems(pImportedObject, s_groupTypeText.toStdWString(), groupTypeAdded, mapIcons, GetIconPathForSKPCategory(), GetIconPathForSKP(), TWNT_GROUP_MODEL_CATEGORY, TWNT_GROUP_MODEL);
}

void QFamilyTreeWidgetUtil::DeleteImportedObjectWidgetItem(QTreeWidget* pTreeWidget, gcmp::IElement* pDeletingObject)
{
    if (pTreeWidget == nullptr)
        return;

    QTreeWidgetItem* pImportedObject = FindTopLevelWidgetItem(pTreeWidget, s_importedObjectText);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pImportedObject, L"pImportedObject为空",L"GDMP",L"2023-10-20");

    gcmp::IElementBasicInformation* pElementBasicInformation = pDeletingObject->GetBasicInformation();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementBasicInformation, L"pElementBasicInformation为空",L"GDMP",L"2023-10-20");

    QTreeWidgetItem* pFamilyItem = nullptr;
    QTreeWidgetItem* pCADSheetItem = FindChildWidgetItem(pImportedObject, s_cadSheetCategoryText.toStdWString());
    if (pCADSheetItem)
    {
        pFamilyItem = FindChildWidgetItem(pCADSheetItem, pElementBasicInformation->GetName());
        if (pFamilyItem)
        {
            OwnerPtr<QTreeWidgetItem> opFamilyItem(pFamilyItem);
            pCADSheetItem->removeChild(pFamilyItem);

            if (pCADSheetItem->childCount() == 0)
            {
                OwnerPtr<QTreeWidgetItem> opCADSheetItem(pCADSheetItem);
                pImportedObject->removeChild(pCADSheetItem);

                if (pImportedObject->childCount() == 0)
                {
                    OwnerPtr<QTreeWidgetItem> opImportedObject(pTreeWidget->takeTopLevelItem(pTreeWidget->indexOfTopLevelItem(pImportedObject)));
                }
            }
        }
    }

    if (!pFamilyItem)
    {
        QTreeWidgetItem* pSKPItem = FindChildWidgetItem(pImportedObject, s_skpCategoryText.toStdWString());
        if (pSKPItem)
        {
            pFamilyItem = FindChildWidgetItem(pSKPItem, pElementBasicInformation->GetName());
            if (pFamilyItem)
            {
                OwnerPtr<QTreeWidgetItem> opFamilyItem(pFamilyItem);
                pSKPItem->removeChild(pFamilyItem);

                if (pSKPItem->childCount() == 0)
                {
                    OwnerPtr<QTreeWidgetItem> opSKPItem(pSKPItem);
                    pImportedObject->removeChild(pSKPItem);

                    if (pImportedObject->childCount() == 0)
                    {
                        OwnerPtr<QTreeWidgetItem> opImportedObject(pTreeWidget->takeTopLevelItem(pTreeWidget->indexOfTopLevelItem(pImportedObject)));
                    }
                }
            }
        }
    }
}

void QFamilyTreeWidgetUtil::BuildGroupObjectWidgetItems(QTreeWidget* pTreeWidget, QIconMap& mapIcons, const std::vector<IElement*>& groupObjects)
{
    if (pTreeWidget == nullptr)
        return;
    // 导入对象 节点
    QTreeWidgetItem* pImportedObject = FindTopLevelWidgetItem(pTreeWidget, s_groupTypeText);
    if (groupObjects.empty())
    {
        if (pImportedObject)
        {
            OwnerPtr<QTreeWidgetItem> opImportedObject(pTreeWidget->takeTopLevelItem(pTreeWidget->indexOfTopLevelItem(pImportedObject)));
        }
        return;
    }

    if (!pImportedObject)
    {
        OwnerPtr<QTreeWidgetItem> opGroupObject = NEW_AS_OWNER_PTR(QTreeWidgetItem, pTreeWidget);
        opGroupObject->setIcon(0, mapIcons.GetIcon(GetIconPathForImportedObject()));
        opGroupObject->setText(0, s_groupTypeText);
        opGroupObject->setData(0, GROUP_USER_DATA_ROLE, QVariant(TWNT_GROUP_OBJECT_ROOT));
        pImportedObject = opGroupObject.get();
        pTreeWidget->insertTopLevelItem(pTreeWidget->topLevelItemCount(), TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opGroupObject));
    }
    DBG_WARN_AND_RETURN_VOID_UNLESS(pImportedObject, L"pImportedObject为空",L"GDMP",L"2023-10-20");

    // GroupType
    std::map<std::wstring, IElement*> groupTypeAdded;
    FOR_EACH(pElement, groupObjects)
    {
        if (IsGroupType(pElement))
        {
            groupTypeAdded.insert(std::make_pair(pElement->GetBasicInformation()->GetName(), pElement));
        }
    }

    ::BuildGroupObjectWidgetItems(pImportedObject, s_groupTypeText.toStdWString(), groupTypeAdded, mapIcons, GetIconPathForSKPCategory(), GetIconPathForSKP(), TWNT_GROUP_MODEL_CATEGORY, TWNT_GROUP_MODEL);
}

void QFamilyTreeWidgetUtil::DeleteGroupObjectWidgetItem(QTreeWidget* pTreeWidget, gcmp::IElement* pDeletingObject)
{
    if (pTreeWidget == nullptr)
        return;

    QTreeWidgetItem* pImportedObject = FindTopLevelWidgetItem(pTreeWidget, s_groupTypeText);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pImportedObject, L"pImportedObject为空",L"GDMP",L"2023-10-20");

    gcmp::IElementBasicInformation* pElementBasicInformation = pDeletingObject->GetBasicInformation();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementBasicInformation, L"pElementBasicInformation为空",L"GDMP",L"2023-10-20");

    QTreeWidgetItem* pFamilyItem = nullptr;
    QTreeWidgetItem* pCADSheetItem = FindChildWidgetItem(pImportedObject, s_groupTypeText.toStdWString());
    if (pCADSheetItem)
    {
        pFamilyItem = FindChildWidgetItem(pCADSheetItem, pElementBasicInformation->GetName());
        if (pFamilyItem)
        {
            OwnerPtr<QTreeWidgetItem> opFamilyItem(pFamilyItem);
            pCADSheetItem->removeChild(pFamilyItem);

            if (pCADSheetItem->childCount() == 0)
            {
                OwnerPtr<QTreeWidgetItem> opCADSheetItem(pCADSheetItem);
                pImportedObject->removeChild(pCADSheetItem);

                if (pImportedObject->childCount() == 0)
                {
                    OwnerPtr<QTreeWidgetItem> opImportedObject(pTreeWidget->takeTopLevelItem(pTreeWidget->indexOfTopLevelItem(pImportedObject)));
                }
            }
        }
    }

}

// 从Family中，去除导入对象的Family，并将其返回
std::vector<IElement*> QFamilyTreeWidgetUtil::FilterOutImportedObjects(std::vector<IFamily*>& pFamilies)
{
    std::vector<IElement*> importedObjects;

    for (auto itr = pFamilies.begin(); itr != pFamilies.end();)
    {
        IFamily* pFamily = *itr;
        auto categoryUid = pFamily->GetBasicInformation()->GetCategoryUid();
        if (categoryUid == BuiltInCategoryUniIdentities::BICU_IMPORTED_SKP_OBJECT)
        {
            importedObjects.push_back(pFamily);
            itr = pFamilies.erase(itr);
        }
        else
        {
            ++itr;
        }
    }

    return importedObjects;
}

void QFamilyTreeWidgetUtil::RemoveSelectedFamlies(QList<QTreeWidgetItem*>& selectedItem, const std::wstring &cmdId)
{
    if (!gcmp::JournalUtils::IsInReplay())
    {
        std::set<std::wstring> deletingFamilies;
        for (QList<QTreeWidgetItem*>::const_iterator iter = selectedItem.begin(); iter != selectedItem.end(); ++iter)
        {
            QTreeWidgetItem *item = *iter;
            QVariant userData = item->data(0, FAMILY_USER_DATA_ROLE);
            QVariant userData2 = item->data(0, IMPORT_USER_DATA_ROLE);
            if (userData.toInt() == TWNT_FAMILY || userData2.toInt() == TWNT_SKP_MODEL) //族节点
            {
                std::wstring familyName;
                if (userData.toInt() == TWNT_FAMILY)
                    familyName = item->text(0).toStdWString();
                else if (userData2.toInt() == TWNT_SKP_MODEL)
                    familyName = item->text(0).toStdWString();

                if (!familyName.empty())
                    deletingFamilies.insert(familyName);
            }
        }

        for (auto iter = deletingFamilies.begin(); iter != deletingFamilies.end(); ++iter)
        {
            gcmp::CommandParameters cmdParams;
            cmdParams[L"FamilyName"] = *iter;

            std::wstring strCmdId = cmdId;
            OwnerPtr<gcmp::IJournalCommandData> opJournalCmdData = IJournalCommandData::Create();
            DBG_WARN_AND_CONTINUE_UNLESS(opJournalCmdData, L"CREATE_JOURNAL_DATA(IJournalCommandData, JOURNAL_COMMAND_DATA)返回空指针",L"GDMP",L"2023-10-20");
            opJournalCmdData->SetCommandName(strCmdId);
            opJournalCmdData->SetParameterArray(cmdParams);
            gcmp::JournalUtils::RecordCommand(TransferOwnership(opJournalCmdData));

            ICommandManager *pCmdMgr = ICommandManager::Get();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pCmdMgr != nullptr, L"pCmdMgr为空",L"GDMP",L"2023-10-20");
            pCmdMgr->SendCommand(strCmdId, cmdParams);
        }
    }
}

void QFamilyTreeWidgetUtil::SaveFamilyAs(QTreeWidgetItem * pTreeItem, const std::wstring &cmdId)
{
    if (pTreeItem == nullptr)
        return;

    QVariant userData = pTreeItem->data(0, FAMILY_USER_DATA_ROLE);
    if (userData.toInt() == TWNT_FAMILY) //族节点
    {
        IUiDocumentViewManager* pUiDocViewMgr = IUiDocumentViewManager::Get();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocViewMgr, L"pUiDocViewMgr为空",L"GDMP",L"2023-10-20");
        gcmp::IDocument* pDoc = pUiDocViewMgr->GetCurrentUiDocument()->GetDbDocument();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc不存在",L"GDMP",L"2023-10-20");

        std::wstring familyName;
        if (userData.toInt() == TWNT_FAMILY)
            familyName = pTreeItem->text(0).toStdWString();
        else if (userData.toInt() == TWNT_CAD_SHEET)
            familyName = pTreeItem->text(0).toStdWString();

        IFamilyConfigElement* pElement = IFamilyConfigElement::GetFamilyConfigElementByName(pDoc, familyName);
        DBG_WARN_AND_RETURN_VOID_UNLESS(pElement, L"FamilyConfigElement个数不对",L"GDMP",L"2023-10-20");

        if (!gcmp::JournalUtils::IsInReplay())
        {
            std::wstring strCmdId = cmdId;
            OwnerPtr<gcmp::IJournalCommandData> opJournalCmdData = IJournalCommandData::Create();
            DBG_WARN_AND_RETURN_VOID_UNLESS(opJournalCmdData, L"CREATE_JOURNAL_DATA(IJournalCommandData, JOURNAL_COMMAND_DATA)返回空指针",L"GDMP",L"2023-10-20");
            opJournalCmdData->SetCommandName(strCmdId);
            gcmp::JournalUtils::StartRecordCommand(TransferOwnership(opJournalCmdData));

            gcmp::CommandParameters cmdParams;
            cmdParams[L"FamilyName"] = pElement->GetFamilyFileName();

            ICommandManager *pCmdMgr = ICommandManager::Get();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pCmdMgr != nullptr, L"pCmdMgr为空",L"GDMP",L"2023-10-20");
            pCmdMgr->SendCommand(strCmdId, cmdParams);
        }
    }
}

void QFamilyTreeWidgetUtil::LoadFamily(QTreeWidgetItem * pTreeItem, const std::wstring &cmdId)
{
    if (pTreeItem == nullptr)
        return;

    QVariant userData = pTreeItem->data(0, FAMILY_USER_DATA_ROLE);
    if (userData.toInt() == TWNT_FAMILY_ROOT) //族节点
    {
        if (!gcmp::JournalUtils::IsInReplay())
        {
            std::wstring strCmdId = cmdId;
            OwnerPtr<gcmp::IJournalCommandData> opJournalCmdData = IJournalCommandData::Create();
            DBG_WARN_AND_RETURN_VOID_UNLESS(opJournalCmdData, L"CREATE_JOURNAL_DATA(IJournalCommandData, JOURNAL_COMMAND_DATA)返回空指针",L"GDMP",L"2023-10-20");
            opJournalCmdData->SetCommandName(strCmdId);
            gcmp::JournalUtils::StartRecordCommand(TransferOwnership(opJournalCmdData));

            ICommandManager *pCmdMgr = ICommandManager::Get();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pCmdMgr != nullptr, L"pCmdMgr为空",L"GDMP",L"2023-10-20");
            pCmdMgr->SendCommand(strCmdId);
        }
    }
}

void QFamilyTreeWidgetUtil::EditFamily(QTreeWidgetItem * pTreeItem, const std::wstring &cmdId)
{
    if (pTreeItem == nullptr)
        return;
    QVariant userData = pTreeItem->data(0, FAMILY_USER_DATA_ROLE);
    if (userData.toInt() == TWNT_FAMILY) //族节点
    {
        std::wstring familyName;
        if (userData.toInt() == TWNT_FAMILY)
            familyName = pTreeItem->text(0).toStdWString();
        else if (userData.toInt() == TWNT_CAD_SHEET)
            familyName = pTreeItem->text(0).toStdWString();

        // 如果family已经打开， 则把family设为当前文档， 否则就打开这个family
        //IUiDocument* pUIDoc = pUIMainWnd->GetUiDocumentViewManager()->GetUiDocumentByName(familyName);
        //if (pUIDoc)
        //{
        //    pUIMainWnd->GetUiDocumentViewManager()->ActivateUiDocument(pUIDoc->GetId());
        //}
        //else
        {
            if (!gcmp::JournalUtils::IsInReplay())
            {
                gcmp::CommandParameters cmdParams;
                cmdParams[L"FamilyInProjectContainer"] = true;
                cmdParams[L"FamilyName"] = familyName;

                std::wstring strCmdId = cmdId;
                OwnerPtr<gcmp::IJournalCommandData> opJournalCmdData = IJournalCommandData::Create();
                DBG_WARN_AND_RETURN_VOID_UNLESS(opJournalCmdData, L"CREATE_JOURNAL_DATA(IJournalCommandData, JOURNAL_COMMAND_DATA)返回空指针",L"GDMP",L"2023-10-20");
                opJournalCmdData->SetCommandName(strCmdId);
                opJournalCmdData->SetParameterArray(cmdParams);
                gcmp::JournalUtils::RecordCommand(TransferOwnership(opJournalCmdData));

                ICommandManager *pCmdMgr = ICommandManager::Get();
                DBG_WARN_AND_RETURN_VOID_UNLESS(pCmdMgr != nullptr, L"pCmdMgr为空",L"GDMP",L"2023-10-20");
                pCmdMgr->SendCommand(L"gmEditFamilyCrossProcess", cmdParams);
            }
        }
    }
}

void QFamilyTreeWidgetUtil::RenameFamily(QTreeWidgetItem * pTreeItem, const std::wstring &cmdId)
{
    if (pTreeItem == nullptr)
        return;
    QVariant userData = pTreeItem->data(0, FAMILY_USER_DATA_ROLE);
    if (userData.toInt() == TWNT_FAMILY) //族节点
    {
        if (!gcmp::JournalUtils::IsInReplay())
        {
            gcmp::CommandParameters cmdParams;
            cmdParams[L"FamilyName"] = pTreeItem->text(0).toStdWString();

            std::wstring strCmdId = cmdId;
            OwnerPtr<gcmp::IJournalCommandData> opJournalCmdData = IJournalCommandData::Create();
            DBG_WARN_AND_RETURN_VOID_UNLESS(opJournalCmdData, L"CREATE_JOURNAL_DATA(IJournalCommandData, JOURNAL_COMMAND_DATA)返回空指针",L"GDMP",L"2023-10-20");
            opJournalCmdData->SetCommandName(strCmdId);
            opJournalCmdData->SetParameterArray(cmdParams);
            gcmp::JournalUtils::RecordCommand(TransferOwnership(opJournalCmdData));

            ICommandManager *pCmdMgr = ICommandManager::Get();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pCmdMgr != nullptr, L"pCmdMgr为空",L"GDMP",L"2023-10-20");
            pCmdMgr->SendCommand(strCmdId, cmdParams);
        }
    }
}

void QFamilyTreeWidgetUtil::CreateFamilyInstance(QTreeWidgetItem * pTreeItem, const std::wstring &cmdId)
{
    if (pTreeItem == nullptr)
        return;

    QVariant userData = pTreeItem->data(0, FAMILY_USER_DATA_ROLE);
    QVariant userData2 = pTreeItem->data(0, IMPORT_USER_DATA_ROLE);
    if (userData.toInt() == TWNT_FAMILYTYPE
        || userData2.toInt() == TWNT_SKP_MODEL) //族类型节点
    {
        QTreeWidgetItem* pParent = pTreeItem->parent();
        if (pParent != nullptr)
        {
            if (!gcmp::JournalUtils::IsInReplay())
            {
                gcmp::CommandParameters cmdParams;
                if (userData.toInt() == TWNT_FAMILYTYPE)
                {
                    cmdParams[L"FamilyName"] = pParent->text(0).toStdWString();
                    cmdParams[L"FamilyType"] = pTreeItem->text(0).toStdWString();
                }
                else if (userData2.toInt() == TWNT_SKP_MODEL)
                {
                    cmdParams[L"FamilyName"] = pTreeItem->text(0).toStdWString();
                    QVariant varFamilyType = pTreeItem->data(0, IMPORT_ITEM_FAMILY_TYPE);
                    DBG_WARN_AND_RETURN_VOID_UNLESS(varFamilyType.isValid() && varFamilyType.canConvert(QVariant::String), L"无效参数",L"GDMP",L"2023-10-20");
                    cmdParams[L"FamilyType"] = varFamilyType.toString().toStdWString();
                }

                std::wstring strCmdId = cmdId;
                OwnerPtr<gcmp::IJournalCommandData> opJournalCmdData = IJournalCommandData::Create();
                DBG_WARN_AND_RETURN_VOID_UNLESS(opJournalCmdData, L"CREATE_JOURNAL_DATA(IJournalCommandData, JOURNAL_COMMAND_DATA)返回空指针",L"GDMP",L"2023-10-20");
                opJournalCmdData->SetCommandName(strCmdId);
                opJournalCmdData->SetParameterArray(cmdParams);
                gcmp::JournalUtils::RecordCommand(TransferOwnership(opJournalCmdData));

                ICommandManager *pCmdMgr = ICommandManager::Get();
                DBG_WARN_AND_RETURN_VOID_UNLESS(pCmdMgr != nullptr, L"pCmdMgr为空",L"GDMP",L"2023-10-20");
                pCmdMgr->SendCommand(strCmdId, cmdParams);
            }
        }
    }
}

void QFamilyTreeWidgetUtil::EditFamilyTypeParameter(QTreeWidgetItem * pTreeItem)
{
    /*/ TODO：支持族编辑

    if (pTreeItem == nullptr)
        return;

    QVariant typeData = pTreeItem->data(0, FAMILY_USER_DATA_ROLE);
    QTreeWidgetItem* pParent = pTreeItem->parent();
    if (pParent != nullptr)
    {
        if (typeData.toInt() == TWNT_FAMILYTYPE) //族类型节点
        {

            if (!gcmp::JournalUtils::IsInReplay())
            {
                gcmp::CommandParameters cmdParams;
                cmdParams[L"FamilyName"] = pParent->text(0).toStdWString();
                cmdParams[L"FamilyType"] = pTreeItem->text(0).toStdWString();

                OwnerPtr<gcmp::IJournalCommandData> opJournalCmdData = IJournalCommandData::Create();
                DBG_WARN_AND_RETURN_VOID_UNLESS(opJournalCmdData, L"CREATE_JOURNAL_DATA(IJournalCommandData, JOURNAL_COMMAND_DATA)返回空指针",L"GDMP",L"2023-10-20");
                // opJournalCmdData->SetCommandName(ID_CMD_FAMILY_EDIT_TYPE_PARAM);
                opJournalCmdData->SetParameterArray(cmdParams);
                gcmp::JournalUtils::RecordCommand(TransferOwnership(opJournalCmdData));

                ICommandManager *pCmdMgr = ICommandManager::Get();
                DBG_WARN_AND_RETURN_VOID_UNLESS(pCmdMgr != nullptr, L"pCmdMgr为空",L"GDMP",L"2023-10-20");
                pCmdMgr->SendCommand(ID_CMD_FAMILY_EDIT_TYPE_PARAM, cmdParams);
            }
        }
    }
    */
}

void QFamilyTreeWidgetUtil::RemoveImportedObject(QTreeWidgetItem * pTreeItem, const std::wstring &cmdId)
{
    return;
    /*/ TODO：支持删除导入CAD

    if (!gcmp::JournalUtils::IsInReplay())
    {
        std::wstring elementName = pTreeItem->text(0).toStdWString();
        CommandParameters cmdParams;
        cmdParams.emplace(IImportCADElement::s_elementNameKey, elementName);

        OwnerPtr<gcmp::IJournalCommandData> opJournalCmdData = IJournalCommandData::Create();
        DBG_WARN_AND_RETURN_VOID_UNLESS(opJournalCmdData, L"CREATE_JOURNAL_DATA(IJournalCommandData, JOURNAL_COMMAND_DATA)返回空指针",L"GDMP",L"2023-10-20");
        opJournalCmdData->SetCommandName(cmdId);
        opJournalCmdData->SetParameterArray(cmdParams);
        gcmp::JournalUtils::RecordCommand(TransferOwnership(opJournalCmdData));

        ICommandManager* pCmdMgr = ICommandManager::Get();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pCmdMgr, L"invalid pCmdMgr",L"GDMP",L"2023-10-20");
        pCmdMgr->SendCommand(cmdId, cmdParams);
    }
    */
}

void QFamilyTreeWidgetUtil::TrigerGroupAction(QTreeWidgetItem * pTreeItem, const std::wstring &cmdId, const std::wstring& actionType)
{
    return;
    /*/ TODO：
    */
    if (!gcmp::JournalUtils::IsInReplay())
    {
        std::wstring elementName = pTreeItem->text(0).toStdWString();
        CommandParameters cmdParams;
        cmdParams.emplace(L"GroupTypeName", elementName);
        cmdParams.emplace(L"ActionType", actionType);

        OwnerPtr<gcmp::IJournalCommandData> opJournalCmdData = IJournalCommandData::Create();
        DBG_WARN_AND_RETURN_VOID_UNLESS(opJournalCmdData, L"CREATE_JOURNAL_DATA(IJournalCommandData, JOURNAL_COMMAND_DATA)返回空指针",L"GDMP",L"2023-10-20");
        opJournalCmdData->SetCommandName(cmdId);
        gcmp::JournalUtils::StartRecordCommand(TransferOwnership(opJournalCmdData));

        ICommandManager* pCmdMgr = ICommandManager::Get();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pCmdMgr, L"invalid pCmdMgr",L"GDMP",L"2023-10-20");
        pCmdMgr->SendCommand(cmdId, cmdParams);
    }
}

void QFamilyTreeWidgetUtil::TrigerGroupListAction(QList<QTreeWidgetItem *> &selectedItem, const std::wstring &cmdId, const std::wstring& actionType)
{
    return;
    /*/ TODO：
    */
    if (!gcmp::JournalUtils::IsInReplay())
    {
        CommandParameters cmdParams;
        cmdParams.emplace(L"ActionType", actionType);
        cmdParams.emplace(L"GroupCount", selectedItem.size());
        for (int i = 0; i < selectedItem.size(); ++i)
        {
            std::wstring elementName = selectedItem[i]->text(0).toStdWString();
            cmdParams.emplace(L"GroupTypeName" + std::to_wstring(i + 1), elementName);
        }
        OwnerPtr<gcmp::IJournalCommandData> opJournalCmdData = IJournalCommandData::Create();
        DBG_WARN_AND_RETURN_VOID_UNLESS(opJournalCmdData, L"CREATE_JOURNAL_DATA(IJournalCommandData, JOURNAL_COMMAND_DATA)返回空指针",L"GDMP",L"2023-10-20");
        opJournalCmdData->SetCommandName(cmdId);
        gcmp::JournalUtils::StartRecordCommand(TransferOwnership(opJournalCmdData));

        ICommandManager* pCmdMgr = ICommandManager::Get();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pCmdMgr, L"invalid pCmdMgr",L"GDMP",L"2023-10-20");
        pCmdMgr->SendCommand(cmdId, cmdParams);
    }
}

